import { message as antdMessage } from 'antd';
import useMessageHooks from 'antd/lib/message/useMessage';
import { ErrorIcon, InfoIcon, Size, SuccessIcon, WarnIcon } from '../Svg';
import { prefix } from '../config';

import type {
  ArgsProps,
  ConfigOptions,
  MessageType,
  NoticeType,
  TypeOpen,
} from 'antd/lib/message/interface';
declare function setMessageGlobalConfig(config: ConfigOptions): void;
interface BaseMethods {
  open: (config: ArgsProps) => MessageType;
  destroy: (key?: React.Key) => void;
  config: typeof setMessageGlobalConfig;
  useMessage: typeof useMessageHooks;
  /** @private Internal Component. Do not use in your production. */
  // _InternalPanelDoNotUseOrYouWillBeFired: typeof PurePanel;
}
interface MessageMethods {
  info: TypeOpen;
  success: TypeOpen;
  error: TypeOpen;
  warning: TypeOpen;
  loading: TypeOpen;
}
export type MessageApi = BaseMethods & MessageMethods;

export type MessageState = NoticeType | 'warn';
type MessageStateApiFn = MessageApi['info'];
type MessageStateApi = {
  [key in MessageState]: MessageStateApiFn;
};
const icons: {
  [key in MessageState]: ((props?: Size) => JSX.Element) | null;
} = {
  success: SuccessIcon,
  info: InfoIcon,
  error: ErrorIcon,
  warning: WarnIcon,
  warn: WarnIcon,
  loading: null,
};
const Keys: MessageState[] = [
  'success',
  'info',
  'error',
  'warning',
  'warn',
  'loading',
];

const api: MessageStateApi = Keys.reduce((api, key) => {
  const fn: MessageStateApiFn = (content, duration, onClose) => {
    const icon = icons[key];
    const config = (content as ArgsProps).content
      ? (content as ArgsProps)
      : { content, duration, onClose };
    const params = Object.assign(
      { type: key, icon: icon && icon({ width: 16, height: 16 }) },
      config,
    );
    return antdMessage.open(params as ArgsProps);
  };
  api[key] = fn;
  return api;
}, {} as MessageStateApi);
const { open, config, destroy, useMessage } = antdMessage;

const message: MessageApi = { open, config, destroy, useMessage, ...api };
message.config({
  prefixCls: prefix.message,
});
export default message;
